<?php
namespace framework\di;

use Exception;

/**
 * Class ServiceLocator
 * @package framework\di
 */
class ServiceLocator
{
    /**
     * @var Container|null
     */
    private $_container = null;

    /**
     * @var array
     */
    private $_components = array();

    /**
     * @var array
     */
    private $_definitions = array();

    /**
     * @param null $container
     */
    public function __construct($container = null)
    {
        $this->_container = $container === null ? new Container() : $container;
    }

    /**
     * 设置组件
     * @param $id
     * @param $definition
     * @param $params
     * @return $this
     */
    public function set($id, $definition,$params=array())
    {
        $this->_definitions[$id] = $definition;
        $this->_container->set($id, $definition,$params);
        return $this;
    }

    /**
     * 获取组件
     * @param $id
     * @return mixed
     * @throws Exception
     */
    public function get($id)
    {
        $this->_components[$id] =  $this->_container->get($id);
        return $this->_components[$id];
    }

    /**
     * 魔术方法,同 get方法
     * @param $id
     * @throws Exception
     */
    public function __get($id)
    {
        if ($this->has($id)) {
            return $this->get($id);
        } else {
            throw new \Exception("Unknown component ID: $id");
        }
    }


    /**
     * 是否存在一个组件
     * @param $id
     * @param bool $checkInstance
     * @return bool
     */
    public function has($id, $checkInstance = false)
    {
        return $checkInstance ? isset($this->_components[$id]) : isset($this->_definitions[$id]);
    }

    /**
     * 清空一个组件
     * @param $id
     */
    public function clear($id)
    {
        unset($this->_definitions[$id], $this->_components[$id]);
    }

}